﻿using Abide_Halo_Library.Windows.Forms;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace Abide_Halo_Library.Halo_2_Map
{
    public partial class TagSelectDialog : Form
    {
        public string Title
        {
            get { return base.Text; }
            set { base.Text = value; }
        }
        public string Description
        {
            get { return descriptionLabel.Text; }
            set { descriptionLabel.Text = value; }
        }
        public IndexEntry SelectedEntry
        {
            get { return selectedEntry; }
            set { selectedEntry = value; }
        }
        public TagSorting Sorting
        {
            get { return sorting; }
            set { sorting = value; }
        }

        private readonly IndexEntry[] entries;
        private IndexEntry selectedEntry;
        private TagSorting sorting;

        public TagSelectDialog(Halo2Map map)
        {
            //Set
            this.entries = new List<IndexEntry>(map.IndexEntries).OrderBy(e => e.Class + e.FileName).ToArray();

            //Initialize
            InitializeComponent();
        }

        private void TagSelectDialog_Load(object sender, EventArgs e)
        {
            //Clear
            tagView.Nodes.Clear();

            //Sorting Type?
            switch (sorting)
            {
                //Class Sorting...
                case TagSorting.Class: BuildClassList(); break;

                //Hierarchial Sorting...
                case TagSorting.Hierarchical: BuildHierarchialList(); break;
            }

            //Collapse
            tagView.CollapseAll();
            tagView.SelectedNode = null;

            //Check
            if (selectedEntry == null)
                return;

            //Prepare
            TreeNodeCollection Collection = null;
            TreeNode ClassNode = null;
            TreeNode EntryNode = null;
            TreeNode Node = null;
            string[] Parts = null;

            switch (sorting)
            {
                case TagSorting.Class:

                    //Get Class Node
                    ClassNode = tagView.Nodes[selectedEntry.Class];
                    ClassNode.Expand();

                    //Get Entry Node
                    EntryNode = ClassNode.Nodes[selectedEntry.Ident.ToString("X")];

                    //Select
                    tagView.SelectedNode = EntryNode;
                    break;

                case TagSorting.Hierarchical:

                    //Setup
                    Collection = tagView.Nodes;

                    //Break
                    Parts = selectedEntry.FileName.Split('\\');

                    //Loop
                    for (int i = 0; i < Parts.Length - 1; i++)
                    {
                        //Get...
                        Node = Collection[Parts[i]];
                        Collection = Node.Nodes;
                        Node.Expand();
                    }

                    //Select Node
                    tagView.SelectedNode = Collection[selectedEntry.Ident.ToString("X")];
                    break;
            }
        }

        private void nullButton_Click(object sender, EventArgs e)
        {
            //Null
            selectedEntry = null;
        }

        private void tagView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            //Prepare
            selectedEntry = null;

            //Check
            if (e.Node.Tag != null && e.Node.Tag is int)
            {
                //Get Ident
                int Ident = (int)e.Node.Tag;

                //Check
                foreach (IndexEntry entry in entries)
                {
                    if (entry.Ident == Ident)
                    {
                        selectedEntry = entry;
                        break;
                    }
                }
            }

            //Enable?
            okButton.Enabled = selectedEntry != null;

            //Check
            if (selectedEntry == null)
                selectionLabel.Text = "Null";
            else
                selectionLabel.Text = string.Format("{0}.{1} ({2:X})", selectedEntry.FileName, selectedEntry.Class, selectedEntry.Ident);
        }

        private void BuildClassList()
        {
            //Prepare
            TreeNode TagNode = null;
            TreeNode ClassNode = null;

            //Loop
            foreach (IndexEntry entry in entries)
            {
                //Get (or create) Class Node
                if (tagView.Nodes.ContainsKey(entry.Class))
                    ClassNode = tagView.Nodes[entry.Class]; //Get
                else
                {
                    //Create
                    ClassNode = new TreeNode(entry.Class);
                    ClassNode.Name = entry.Class;
                    ClassNode.Tag = -1;

                    //Add
                    tagView.Nodes.Add(ClassNode);
                }

                //Create TagNode
                TagNode = new TreeNode(entry.FileName);
                TagNode.Name = entry.Ident.ToString("X");
                TagNode.Tag = entry.Ident;

                //Add
                ClassNode.Nodes.Add(TagNode);
            }
        }

        private void BuildHierarchialList()
        {
            //Prepare
            TreeNode Node = null;
            TreeNodeCollection CurrentCollection = null;
            string[] Parts = null;

            //Loop
            foreach (IndexEntry entry in entries)
            {
                //Prepare
                Parts = entry.FileName.Split('\\');
                CurrentCollection = tagView.Nodes;

                //Loop
                for (int i = 0; i < Parts.Length - 1; i++)
                {
                    if (CurrentCollection.ContainsKey(Parts[i]))
                        CurrentCollection = CurrentCollection[Parts[i]].Nodes;
                    else
                    {
                        Node = new TreeNode(Parts[i]);
                        Node.Name = Parts[i];
                        Node.Tag = -1;

                        CurrentCollection.Add(Node);
                        CurrentCollection = Node.Nodes;
                    }
                }

                //Create Node
                Node = new TreeNode(string.Format("{0}.{1}", Parts[Parts.Length - 1], entry.Class));
                Node.Name = entry.Ident.ToString("X");
                Node.Tag = entry.Ident;

                //Add
                CurrentCollection.Add(Node);
            }
        }
    }
}
